package com.wan.paypal.controller;


import com.wan.paypal.config.PaypalConfig;
import com.wan.paypal.config.PaypalPaymentIntent;
import com.wan.paypal.config.PaypalPaymentMethod;
import com.wan.paypal.service.PaypalService;
import com.wan.paypal.utils.URLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;

@Controller
@RequestMapping("/v1")
public class PaymentController {
//    @Autowired
//    private APIContext apiContext;
//    @Autowired
//    private PaypalConfig paypalConfig;
//    @Autowired
//    private PaypalService paypalService;
//    private ConcurrentHashMap<String, String> orderPaymMap = new ConcurrentHashMap();// orderId与paymentId的对应关系
//    private Logger log = LoggerFactory.getLogger(getClass());
//
//    /**
//     * 首页
//     */
//    @RequestMapping(method = RequestMethod.GET)
//    public String index() {
//        return "index";
//    }
//
//    /**
//     * 创建订单请求
//     * 创建成功返回payment对象，保存本地OrderId和paymentId对应关系
//     */
//    @RequestMapping(method = RequestMethod.POST, value = "pay")
//    public String pay(HttpServletRequest request) {
//        log.info("=========================================================================================");
//        String orderId = "2020110200001";// 本地系统Id
//        String cancelUrl = URLUtils.getBaseURl(request) + "/" + PaypalConfig.CANCEL_URL + "?orderId=" + orderId;// http://localhost:8080/pay/cancel
//        String successUrl = URLUtils.getBaseURl(request) + "/" + PaypalConfig.SUCCESS_URL;
//        try {
//            //调用交易方法
//            Payment payment = paypalService.createPayment(
//                    orderId,
//                    300.00,
//                    "USD",
//                    PaypalPaymentMethod.paypal,
//                    PaypalPaymentIntent.authorize,
//                    "这是一笔300美元的交易",
//                    cancelUrl,
//                    successUrl);
//            for (Links links : payment.getLinks()) {
//                if (links.getRel().equals("approval_url")) {
//                    // 客户付款登陆地址【判断币种CNY无法交易】
//                    String paymentId = payment.getId();
//                    orderPaymMap.put(orderId, paymentId);// 保存本地OrderId和paymentId对应关系
//                    log.info("创建支付订单返回paymentId : " + paymentId);
//                    log.info("支付订单状态state : " + payment.getState());
//                    log.info("支付订单创建时间create_time : " + payment.getCreateTime());
//                    log.info("=========================================================================================");
//                    return "redirect:" + links.getHref();
//                }
//            }
//        } catch (PayPalRESTException e) {
//            log.error(e.getMessage());// 支付失败【使用CNY】
//        }
//        log.info("=========================================================================================");
//        return "redirect:/";
//    }
//
//    /**
//     * 失败回调
//     *   触发回调情景：
//     *     1、用户在支付页面点击取消支付
//     *     2、用户支付成功后点击网页回退，再点击返回商家按钮触发
//     *   判断是否用户主动取消付款逻辑：
//     *     1、设置回调地址的时候拼接本地订单ID：?orderId=XXXX
//     *     2、然后根据orderId查询paymentId，继而调用sdk查询订单支付状态
//     *      * http://localhost:8080/pay/cancel?orderId=2020110200001&token=EC-70674489LL9806126
//     */
//    @RequestMapping(method = RequestMethod.GET, value = PaypalConfig.CANCEL_URL)
//    public String cancelPay(@RequestParam("token") String token, @RequestParam("orderId") String orderId) {
//        try {
//            String paymentId = orderPaymMap.get(orderId);
//            Payment payment = Payment.get(apiContext, paymentId);
//            String state = payment.getState();
//            log.info("交易取消回调：支付订单状态：{} ", state);
//            if (state.equals("approved")) {// 已支付
//                return "success";
//            }
//        } catch (PayPalRESTException e) {
//            e.printStackTrace();
//        }
//        return "cancel";
//    }
//
//    /**
//     * 成功回调 + 支付 + PDT同步通知
//     *    买家确认付款，执行支付并直接返回通知
//     */
//    @RequestMapping(method = RequestMethod.GET, value = PaypalConfig.SUCCESS_URL)
//    public String successPay(@RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId, @RequestParam("token") String token) {
//        log.info("=========================================================================================");
//        try {
//            /**
//             * 执行支付
//             */
//            Payment payment = paypalService.executePayment(paymentId, payerId);
//            if (payment.getState().equals("approved")) {
//                String id = "";     // 交易ID，transactionId
//                String state = "";  // 交易订单状态
//                String time = "";   // 交易时间
//                String custom = ""; // 本地OrderId
//                if (payment.getIntent().equals(PaypalPaymentIntent.authorize.toString())) {
//                    id = payment.getTransactions().get(0).getRelatedResources().get(0).getAuthorization().getId();
//                    state = payment.getTransactions().get(0).getRelatedResources().get(0).getAuthorization().getState();
//                    time = payment.getTransactions().get(0).getRelatedResources().get(0).getAuthorization().getCreateTime();
//                    custom = payment.getTransactions().get(0).getCustom();
//                } else if (payment.getIntent().equals(PaypalPaymentIntent.sale.toString())) {
//                    id = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getId();
//                    state = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getState();
//                    time = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getCreateTime();
//                    custom = payment.getTransactions().get(0).getCustom();
//                } else if (payment.getIntent().equals(PaypalPaymentIntent.order.toString())) {
//                    id = payment.getTransactions().get(0).getRelatedResources().get(0).getOrder().getId();
//                    state = payment.getTransactions().get(0).getRelatedResources().get(0).getOrder().getState();
//                    time = payment.getTransactions().get(0).getRelatedResources().get(0).getOrder().getCreateTime();
//                    custom = payment.getTransactions().get(0).getCustom();
//                }
//                log.info("PDT通知：交易成功回调");
//                log.info("付款人账户：" + payment.getPayer().getPayerInfo().getEmail());
//                log.info("支付订单Id {}", paymentId);
//                log.info("支付订单状态state : " + payment.getState());
//                log.info("交易订单Id：{}", id);
//                log.info("交易订单状态state : " + state);
//                log.info("交易订单支付时间：" + time);
//                log.info("本地系统OrderId：{}", custom);
//                log.info("=========================================================================================");
//                return "success";
//            }
//        } catch (PayPalRESTException e) {
//            // 如果同步通知返回异常，可根据paymentId 来查询刷新订单状态
//            // 同时IPN异步通知也可以更新订单状态
//            log.error(e.getMessage());
//        }
//        return "redirect:/";
//    }
//
//    /**
//     * IPN异步通知
//     *   触发情景：
//     *      1、买家支付成功
//     *      2、卖家确认收取授权或订单款项
//     *      3、卖家发放退款
//     */
//    @RequestMapping(method = RequestMethod.POST, value = "/notificationIPN", produces = "application/json;charset=utf-8")
//    public void receivePaypalStatus(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        log.info("=========================================================================================");
//        log.info("IPN通知：异步回调");
//        PrintWriter out = response.getWriter();
//        try {
//            Enumeration<String> en = request.getParameterNames();
//            /**
//             * 修改订单状态
//             *      保存失败则不验签，继续接受paypal异步回调直至保存成功【或者用MQ】
//             */
//            String paymentStatus = request.getParameter("payment_status").toUpperCase();  // 交易状态
//            String paymentDate = request.getParameter("payment_date");      // 交易时间
//            String custom = request.getParameter("custom");                 // 本地系统订单ID
//            String auth_id = request.getParameter("auth_id");               // transactionId
//            String txnId = request.getParameter("txn_id");                  // 当前回调数据id【具体逻辑查看 .md文档】
//            String parentTxnId = request.getParameter("parent_txn_id");     // 父id
//            String receiverEmail = request.getParameter("receiver_email");  // 收款人email
//            String receiverId = request.getParameter("receiver_id");        // 收款人id
//            String payerEmail = request.getParameter("payer_email");        // 付款人email
//            String payerId = request.getParameter("payer_id");              // 付款人id
//            String mcGross = request.getParameter("mc_gross");              // 交易金额
//            String item_name = request.getParameter("item_name");
//            log.info("paymentStatus = " + paymentStatus);
//            log.info("txnId = " + txnId);
//            log.info("parentTxnId = " + parentTxnId);
//            log.info("authId（transactionId）= " + auth_id);
//            log.info("custom（orderId）= " + custom);
//            log.info("request item_name= " + item_name);
//            //log.info("request item_name= " + new String(request.getParameter("item_name").getBytes("ISO-8859-1"), "UTF-8"));
//            //log.info("item_name= " + new String(item_name.getBytes("ISO-8859-1"), "UTF-8"));
//            //log.info("URLDecoder item_name= " + new String(URLDecoder.decode(request.getParameter("item_name"), "ISO-8859-1")));
//            /**
//             * 验证
//             *   作用：
//             *     订单状态修改成功，告诉paypal停止回调
//             *   实现：
//             *     在原参数的基础上加cmd=_notify-validate，然后对https://www.sandbox.paypal.com/cgi-bin/webscr发起POST验证请求
//             */
//            String str = "cmd=_notify-validate";
//            while (en.hasMoreElements()) {
//                String paramName = en.nextElement();
//                String paramValue = request.getParameter(paramName);
//                //此处的编码一定要和自己的网站编码一致，不然会出现乱码，paypal回复的通知为"INVALID"
//                str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue, "utf-8");
//            }
//            log.info("paypal传递过来的交易信息:" + str);// 建议在此将接受到的信息 str 记录到日志文件中以确认是否收到 IPN 信息
//            URL url = new URL(paypalConfig.getWebscr());
//            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//            connection.setRequestMethod("POST");
//            connection.setDoOutput(true);
//            connection.setDoInput(true);
//            connection.setUseCaches(false);
//            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//设置 HTTP 的头信息
//            PrintWriter pw = new PrintWriter(connection.getOutputStream());
//            pw.println(str);
//            pw.close();
//            /**
//             * 回复
//             *    接受PayPal对验证的回复信息
//             */
//            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//            String resp = in.readLine();
//            in.close();
//            resp = StringUtils.isEmpty(resp) ? "0" : resp;
//            log.info("resp = " + resp);
//            /**
//             * 验证返回状态
//             */
//            if (PaypalConfig.PAYMENT_IPN_VERIFIED.equalsIgnoreCase(resp)) {
//                /**
//                 * 修改订单状态
//                 *      根据订单状态paymentStatus确定当前回调的类型
//                 */
//                switch (paymentStatus) {
//                    case PaypalConfig.PAYMENT_STATUS_PENDING:
//                        // 商家待领取状态
//                        break;
//                    case PaypalConfig.PAYMENT_STATUS_VOIDED:
//                        // 商家作废（30天以内，且必须是授权付款类型 或 订单付款类型），款项原路返回买家
//                        break;
//                    case PaypalConfig.PAYMENT_STATUS_COMPLETED:
//                        // 商家领取
//                        String captureId = txnId;   // 实际领取对象ID【授权付款 和 订单付款需要商家领取】
//                        break;
//                    case PaypalConfig.PAYMENT_STATUS_REFUNDED:
//                        // 商家退款，需扣除费用
//                        String refundId = txnId;
//                        String captureId2 = parentTxnId;
//                        break;
//                }
//            } else if (PaypalConfig.PAYMENT_IPN_INVALID.equalsIgnoreCase(resp)) {
//                // 非法信息，可以将此记录到您的日志文件中以备调查
//                log.error("IPN通知返回状态非法，请联系管理员，请求参数：" + str);
//                log.error("Class: " + this.getClass().getName() + " method: " + Thread.currentThread().getStackTrace()[1].getMethodName());
//                out.println("confirmError");
//            } else {// 处理其他错误
//                log.error("IPN通知返回状态非法，请联系管理员，请求参数：" + str);
//                log.error("Class: " + this.getClass().getName() + " method: " + Thread.currentThread().getStackTrace()[1].getMethodName());
//                out.println("confirmError");
//            }
//        } catch (Exception e) {
//            log.error("IPN通知发生IO异常" + e.getMessage());
//            log.error("Class: " + this.getClass().getName() + " method: " + Thread.currentThread().getStackTrace()[1].getMethodName());
//            out.println("confirmError");
//            e.printStackTrace();
//        }
//        out.flush();
//        out.close();
//        log.info("=========================================================================================");
//    }
//
//    /**
//     * 查看已付款账单的状态
//     */
//    @RequestMapping(method = RequestMethod.GET, value = "test")
//    @ResponseBody
//    public String selectTransactionState(@RequestParam("paymentId") String paymentId) {
//        log.info("=========================================================================================");
//        String state = "未产生支付信息";
//        String custom = "";
//        try {
//            Payment payment = Payment.get(apiContext, paymentId);
//            if (payment.getTransactions().size() > 0 && payment.getTransactions().get(0).getRelatedResources().size() > 0) {
//                if (payment.getIntent().equals(PaypalPaymentIntent.sale.toString())) {// 交易订单
//                    state = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getState();
//                    custom = payment.getTransactions().get(0).getCustom();
//                } else if (payment.getIntent().equals(PaypalPaymentIntent.authorize.toString())) {// 授权订单
//                    state = payment.getTransactions().get(0).getRelatedResources().get(0).getAuthorization().getState();
//                    custom = payment.getTransactions().get(0).getCustom();
//                } else if (payment.getIntent().equals(PaypalPaymentIntent.order.toString())) {// 授权订单
//                    state = payment.getTransactions().get(0).getRelatedResources().get(0).getOrder().getState();
//                    custom = payment.getTransactions().get(0).getCustom();
//                }
//            }
//        } catch (PayPalRESTException e) {
//            e.printStackTrace();
//        }
//        log.info("订单状态：{} ", state);
//        log.info(custom);
//        log.info("=========================================================================================");
//        return state;
//    }
}